<template>
  <view class="container">
    <!-- 顶部标题 -->
   <!-- <view class="header">
      <text class="title">视力筛查控制端</text>
    </view> -->
    <!-- 信息显示区 - 卡片式布局 -->
    <view class="info-card">
		<view class="info-section">
		  <view class="device-info-display">
		    <!-- E字画布和视力值显示 -->
		    <view class="vision-display-area">
		      <text class="level-vision">{{ currentVision || '5.0' }}</text>
		      <view class="e-chart-container">
		        <canvas 
		          class="e-canvas" 
		          canvas-id="eCanvas"
		          :width="150" 
		          :height="150"
		          :style="{ transform: `rotate(${currentDirection * 90}deg)` }"
		        ></canvas>
		      </view>
		      <text class="decimal-vision">{{ decimalVision || '1.0' }}</text>
		    </view>
		    
		    <!-- 底部状态行 -->
		    <view class="status-line">
		      <view class="distance-info">
		        <uni-icons type="location-filled" size="24" color="#000"></uni-icons>
		        <text class="test-distance">{{ currentDistance }}M</text>
		      </view>
		     <!-- <view class="direction-info">
		        <text class="direction-value">{{ currentVision2 || '5.0(1.0)' }}</text>
		      </view> -->
		      <view class="status-info">
		        <text class="status-dot" :class="{ 'connected': isConnected, 'blink': isConnected }">●</text>
		        <text class="connect-status" :class="{ 'connected': isConnected }">{{ isConnected ? '已连接' : '未连接' }}</text>
		      </view>
		    </view>
		  </view>
		</view>
      <view class="divider"></view>

      <view class="info-section">
<!--        <text class="section-title">筛查信息</text> -->
        <view class="info-row">
          <text>用户信息：</text>
          <text class="info-value">{{ patientName || '--' }}  {{ patientId || '' }} {{ classInfo || '' }}</text>
        </view>
       <!-- <view class="info-row">
          <text>筛查编号：</text>
          <text class="info-value">{{ patientId || '--' }}</text>
        </view> -->
        <!-- <view class="info-row">
          <text>班级信息：</text>
          <text class="info-value">{{ classInfo || '--' }}</text>
        </view> -->
		<view class="info-row">
		  <text>矫正方式：</text>
		  <picker :range="correctionOptions" :value="correctionIndex" @change="onCorrectionChange">
		    <view class="picker-view">{{ correctionOptions[correctionIndex] || '请选择' }}</view>
		  </picker>
		</view>
        <view class="vision-row">
          <view class="eye-vision">
            <text>右眼视力：</text>
            <text class="vision-value">{{ rightEyeVision || '--' }}</text>
          </view>
          <view class="eye-vision">
            <text>左眼视力：</text>
            <text class="vision-value">{{ leftEyeVision || '--' }}</text>
          </view>
        </view>
      </view>
    </view>

    <!-- 九宫格控制区 -->
    <view class="grid-container">
	  <view class="grid-row">
		<button class="grid-btn" @click="getVision('right')">右眼</button>
		<button class="grid-btn" @click="getVision('left')">左眼</button>
	  </view>
      <view class="grid-row">
		<button class="grid-btn" @click="sendReset">重置</button>
        <button class="grid-btn" @click="sendPrevCommand">上级</button>
		<button class="grid-btn" @click="scanQRCode">扫码</button>
      </view>
      <view class="grid-row">
        <button class="grid-btn" @click="sendRotateCommand">旋转</button>
        <button class="grid-btn" style="background-color: #67e3cb;" @click="saveResult">保存</button>
        <button class="grid-btn" @click="randomVision">随机</button>
      </view>
      <view class="grid-row">
		<button class="grid-btn" @click="toggleConnection">连接</button>
        <button class="grid-btn" @click="sendNextCommand">下级</button>
		<button class="grid-btn" @click="showSettings">设置</button>
      </view>
    </view>

    <!-- 更多设置弹窗 -->
    <uni-popup ref="settingsPopup" type="center">
      <view class="custom-dialog">
        <view class="dialog-header">
          <text class="dialog-title">设置</text>
          <uni-icons 
            type="closeempty" 
            size="20" 
            @click="closeSettings"
            class="close-icon">
          </uni-icons>
        </view>
        <view class="dialog-body">
         <!-- <view class="setting-item">
            <text class="setting-label">WebSocket地址</text>
            <input class="setting-input" v-model="wsUrl" placeholder="ws://ip:port" />
          </view> -->
          <view class="setting-item">
            <text class="setting-label">连接设备</text>
            <view class="input-container">
              <input 
                class="setting-input" 
                v-model="targetDeviceId" 
                placeholder="输入设备ID或扫码" 
              />
              <button class="scan-btn" @click="scanDeviceId">
                <uni-icons type="scan" size="16" color="#666"></uni-icons>
              </button>
            </view>
            <button class="connect-btn" @click="toggleConnection">
              {{ isConnected ? '断开连接' : '连接设备' }}
            </button>
          </view>
          
          <view class="setting-item">
            <text class="setting-label">筛查距离</text>
            <radio-group class="distance-radio" @change="distanceChange">
              <label class="radio-item">
                <radio value="5" :checked="currentDistance === 5" />
                <text>5米(标准)</text>
              </label>
              <label class="radio-item">
                <radio value="3" :checked="currentDistance === 3" />
                <text>3米</text>
              </label>
              <label class="radio-item">
                <radio value="2.5" :checked="currentDistance === 2.5" />
                <text>2.5米</text>
              </label>
            </radio-group>
          </view>
          
          <view class="setting-item">
            <text class="setting-label">初始值视力</text>
            <picker :range="visionOptions.map(option => option.label)" :value="defaultVisionIndex" @change="defaultVisionChange">
              <view class="picker-view">当前选择：{{ visionOptions[defaultVisionIndex].label }}</view>
            </picker>
          </view>
          
          <view class="setting-item">
            <text class="setting-label">显示日志</text>
            <switch class="log-switch" :checked="!!showLogs" @change="(e) => toggleLogs(e.detail.value)" />
          </view>
        </view>
      </view>
    </uni-popup>

    <!-- 日志面板 -->
    <uni-popup ref="logPopup" type="bottom" :show="showLogs">
      <view class="log-panel">
        <view class="log-header">
          <text class="log-title">通信日志</text>
          <button class="clear-btn" @click="clearLogs">
            <uni-icons type="trash" size="16" color="#666"></uni-icons>
          </button>
        </view>
        <scroll-view class="log-content" scroll-y>
          <view class="log-item" v-for="(log, index) in logs" :key="index">
            <text class="log-time">[{{ log.time }}]</text>
            <text class="log-message">{{ log.message }}</text>
          </view>
        </scroll-view>
      </view>
    </uni-popup>
  </view>
</template>

<script>
import {smYkScreenAdd } from "@/api/files/screenPlanInfo";	
// import uniPopup from '@dcloudio/uni-ui/lib/uni-popup/uni-popup.vue'
// import uniPopupDialog from '@dcloudio/uni-ui/lib/uni-popup-dialog/uni-popup-dialog.vue'

export default {
  // components: {
  //   uniPopup,
  //   uniPopupDialog
  // },
  data() {
    // 创建从5.3到4.0的视力选项数组
	 const visionLevels= [
			{ label: '4.8', value: 8 },
			{ label: '4.9', value: 9 },
			{ label: '5.0', value: 10 }
		  ];
    // 找到4.8的默认索引
    const defaultIndex = visionLevels.findIndex(level => level === '4.8');
    return {
      // WebSocket相关
      wsUrl: 'ws://8.140.55.249:8099',
      isConnected: false,
      socketTask: null,
      currentDeviceId: 'device_' + Math.random().toString(36).substr(2, 8),
      targetDeviceId: '',
      pendingCommands: new Map(),
      logs: [],
      showLogs: false,
	  
	  //心跳检测
	  heartBeat: {
	    pingInterval: 25000,   // 心跳间隔
	    pongTimeout: 5000,     // 等待服务器回应的最长时间
	    maxLost: 2             // 连续几次没回应就重连
	  },
	  
	  lostCount: 0,            // 当前已连续丢失几次
	  heartTimer: null,        // 保存 setInterval id
	  btnLock: {},             // key 是按钮名，value 是 true/false
      // 筛查信息
	  planId:'',//筛查计划编号
      patientName: '',
      patientId: '',
      classInfo: '',
      currentVision: '5.0',
	  decimalVision: '1.0',
      currentVision2: '5.0(1.0)',
	  currentDirection: 0, //方向
      rightEyeVision: '',
      leftEyeVision: '',
	  correctionOptions: ['未矫正','框架眼镜', '隐形银镜', '角膜塑形镜', '有镜未带', '其他'],
	  correctionIndex: 0, // 默认选择第一项
      issljz: '否',//是否视力矫正
	  jzfs: '', //矫正方式
	  screenType: 'F', //筛查类型 1校筛 2-日筛查
      // 设置相关
      currentDistance: 5,
      
      // 视力选项相关
	  currentDefaultVision: 8,
      visionOptions: visionLevels,
      defaultVisionIndex: defaultIndex >= 0 ? defaultIndex : 0,
    }
  },
  onUnload() {
    this.disconnectWebSocket()
  },
   // 页面显示时初始化绘制
  onLoad() {
	  this.$nextTick(() => {
		setTimeout(() => {
		   this.drawEChar(this.currentDirection); 
		}, 200); // 增加延迟确保Canvas已渲染
	  });
	},
  methods: {
    // WebSocket连接管理
    toggleConnection() {
      if (this.isConnected) {
        this.disconnectWebSocket()
      } else {
        this.connectWebSocket()
      }
    },
    
    connectWebSocket() {
      if (this.socketTask) return
	  if (!this.targetDeviceId) {
	    uni.showToast({ title: '请设置目标设备ID', icon: 'none' })
	    return
	   }
	  this.wsUrl=this.wsUrl+'?deviceId='+this.currentDeviceId
      this.addLog(`⌛ 正在连接: ${this.wsUrl}`)
      uni.showLoading({ title: '连接中...' })
      this.socketTask = uni.connectSocket({
        url: this.wsUrl,
        complete: () => {}
      })
      
      this.socketTask.onOpen(() => {
        this.isConnected = true
        uni.hideLoading()
        this.addLog('✅ WebSocket连接成功')
        uni.showToast({ title: '连接成功', icon: 'success' })
		// 启动心跳
		  //this.startHeartBeat()
         // 连接成功后发送初始视力设置
        this.sendReset()
      })
      
      this.socketTask.onMessage((res) => {
        try {
          const msg = JSON.parse(res.data)
          this.addLog(`⬇️ 收到: ${JSON.stringify(msg)}`)
          
          if (msg.type === 'ack') {
            const pendingCmd = this.pendingCommands.get(msg.msgId)
            if (pendingCmd) {
              clearTimeout(pendingCmd.timer)
              this.pendingCommands.delete(msg.msgId)
              this.addLog(`✔️ 指令 ${msg.msgId} 已确认`)
            }
            if (msg.status === 'error') {
              uni.showToast({ title: msg.message, icon: 'none' })
			  this.disconnectWebSocket()
              return;
            }
          } else {
            this.handleVisionData(msg);
          }
        } catch (e) {
          this.addLog(`📨 非JSON消息: ${res.data}`)
          uni.showToast({ title: '接收消息错误', icon: 'none' })
        }
      })
      
      this.socketTask.onError((err) => {
        this.addLog(`❌ 连接错误: ${err.errMsg}`)
        this.disconnectWebSocket()
        uni.showToast({ title: '连接错误', icon: 'none' })
      })
      
      this.socketTask.onClose(() => {
        this.addLog('⚠️ 连接已关闭')
        this.disconnectWebSocket()
        uni.showToast({ title: '连接已关闭', icon: 'none' })
      })
    },
    
    disconnectWebSocket() {
	  // this.stopHeartBeat()   // 停止心跳
      if (this.socketTask) {
        this.socketTask.close()
        this.socketTask = null
      }
      this.isConnected = false
      //this.currentDeviceId = ''
    },
	startHeartBeat() {
	  // 如果已有定时器先清掉
	  if (this.heartTimer) clearInterval(this.heartTimer)
	
	  this.lostCount = 0
	  this.heartTimer = setInterval(() => {
	    // 发 ping
	    const pingMsg = {
	      type: 'ping',
	      msgId: 'ping_' + Date.now()
	    }
	    this.socketTask.send({ data: JSON.stringify(pingMsg) })
	
	    // 设定超时检测
	    const timer = setTimeout(() => {
	      this.lostCount++
	      this.addLog(`❤️ ping 丢失 ${this.lostCount}/${this.heartBeat.maxLost}`)
	      if (this.lostCount >= this.heartBeat.maxLost) {
	        this.addLog('❤️ 心跳超时，准备重连')
	        this.disconnectWebSocket()
	        // 自动重连
	        setTimeout(() => this.connectWebSocket(), 1000)
	      }
	    }, this.heartBeat.pongTimeout)
	
	    // 收到任何消息都算“活着”，把计数清零
	    const clearLost = () => {
	      clearTimeout(timer)
	      this.lostCount = 0
	    }
	    this.socketTask.onMessage(clearLost)
	  }, this.heartBeat.pingInterval)
	},
	
	stopHeartBeat() {
	  if (this.heartTimer) {
	    clearInterval(this.heartTimer)
	    this.heartTimer = null
	  }
	},
	
    // 指令发送
    sendCommand(command, data = {}) {
      if (!this.isConnected) {
        uni.showToast({ title: '未连接设备', icon: 'none' })
        return
      }
      
      if (!this.targetDeviceId) {
        uni.showToast({ title: '请设置目标设备ID', icon: 'none' })
        return
      }
      
      const msg = {
        type: 'unicast',
        msgId: 'cmd_' + Date.now(),
        status: 'control',
        command: command,
        distance: this.currentDistance,
		defaultVision: this.currentDefaultVision,
        targetDeviceId: this.targetDeviceId,
        senderDeviceId: this.currentDeviceId,
        timestamp: Date.now(),
        data: data,
      }
      
      this.pendingCommands.set(msg.msgId, {
        timer: setTimeout(() => {
          this.addLog(`⌛ 指令 ${msg.msgId} 超时未响应`)
          this.pendingCommands.delete(msg.msgId)
          uni.showToast({ title: '超时未响应', icon: 'none' })
        }, 5000)
      })
      
      this.socketTask.send({
        data: JSON.stringify(msg),
        success: () => {
          this.addLog(`⬆️ 发送: ${command} ${JSON.stringify(data)}`)
        },
        fail: (err) => {
          this.addLog(`❌ 发送失败: ${err.errMsg}`)
          uni.showToast({ title: '发送失败', icon: 'none' })
        }
      })
    },
	
    // 处理视力数据
    handleVisionData(msg) {
      if (msg.visionData) {
		 //  const directionCode= msg.visionData.direction;
		 //  if(directionCode===1){
			// this.currentDirection='下';
		 //  }else if(directionCode===2){
			// this.currentDirection='左';
		 //  }else if(directionCode===3){
			// this.currentDirection='上';
		 //  }else if(directionCode===0){
			// this.currentDirection='右';
		 //  }
		
	    this.currentDirection = msg.visionData.direction; 
        this.currentVision2 = msg.visionData.levelVision + '(' + msg.visionData.decimalVision + ')'
        this.currentVision = msg.visionData.levelVision
		this.decimalVision = msg.visionData.decimalVision
        this.currentDistance = msg.visionData.distance || this.currentDistance
      }
    },
	// 绘制E字标
	drawEChar(direction = 0) {
	  const ctx = uni.createCanvasContext('eCanvas', this);
	  const size = 120; // 画布大小
	  const center = size / 2;
	  const barWidth = size / 8; // E字笔画宽度
	  const eWidth = size * 0.6;  // E字宽度
	  const eHeight = size * 0.6; // E字高度

	  // 清空画布
	  ctx.clearRect(0, 0, size, size);
	  // 设置样式 - 使用黑色
	  ctx.setFillStyle('#000000');
	  ctx.setLineJoin('round');
	  // 根据方向旋转画布
	  ctx.translate(center, center);
	  ctx.rotate(direction * Math.PI / 2); // 0°、90°、180°、270°
	  ctx.translate(-center, -center);
	  
	  // 计算E字的起始位置（居中显示）
	  const startX = center - eWidth / 2;
	  const startY = center - eHeight / 2;
	  // 绘制E字 - 更精确的坐标计算
	  // 竖线（左边）
	  ctx.fillRect(startX, startY, barWidth, eHeight);
	  // 上横线
	  ctx.fillRect(startX, startY, eWidth, barWidth);
	  // 中横线
      ctx.fillRect(startX, center - barWidth/2, eWidth, barWidth);
	  // 下横线 - 修正位置
	  ctx.fillRect(startX, startY + eHeight - barWidth, eWidth, barWidth);
	  ctx.draw(true);
	},
	 // 把任何需要防抖的函数包一层
	  debounceBtn(key, fn, delay = 1000 ) {
	    if (this.btnLock[key]) return          // 还在冷却
	    this.btnLock[key] = true               // 上锁
	    fn()                                   // 真正执行
	    setTimeout(() => this.btnLock[key] = false, delay) // 解锁
	  },
	
	//旋转
   sendRotateCommand() {
       this.debounceBtn('rotate', () => {
         this.sendCommand('rotate')
       })
     },
    
	//随机
     randomVision() {
        this.debounceBtn('random', () => {
          this.sendCommand('random')
        })
      },

    
	//下级
     sendNextCommand() {
        this.debounceBtn('next', () => {
          this.sendCommand('next')
        })
      },
    
	//上级
   sendPrevCommand() {
      this.debounceBtn('prev', () => {
        this.sendCommand('prev')
      })
    },
	
	//重置
	sendReset(){
	 this.planId='',
	 this.patientName='',
	 this.patientId='',
	 this.classInfo='',
	 this.rightEyeVision='',
	 this.leftEyeVision='',
	 this.correctionIndex=0, // 默认选择第一项
	 this.issljz='否',//是否视力矫正
	 this.jzfs='', //矫正方式
	 this.screenType='F',
	 this.sendCommand('reset')
	},
	
    // 获取视力值
    getVision(eye) {
       this.debounceBtn('getVision', () => {
         if (eye === 'right') {
           this.rightEyeVision = this.currentVision
         } else if (eye === 'left') {
           this.leftEyeVision = this.currentVision
         }
       })
     },
	
    // 保存
async saveResult() {
  // 1. 立即显示加载提示
  uni.showLoading({ 
    title: '保存中...', 
    mask: true 
  })
  
  console.log('🔍 【开始保存】数据:', {
    planId: this.planId,
    studentName: this.patientName,
    studentId: this.patientId,
    rightEye: this.rightEyeVision,
    leftEye: this.leftEyeVision,
    issljz: this.issljz,
    jzfs: this.jzfs,
	screenType: this.screenType
  })
  
  try {
    // 2. 基本验证
	if (!this.planId) {
	  throw new Error('筛查编号不能为空')
	}
    if (!this.patientName) {
      throw new Error('筛查姓名不能为空')
    }
    if (!this.patientId) {
      throw new Error('档案编号不能为空')
    }
    if (!this.rightEyeVision) {
      throw new Error('右眼视力不能为空')
    }
    if (!this.leftEyeVision) {
      throw new Error('左眼视力不能为空')
    }
    if (!this.issljz) {
      throw new Error('请选择是否矫正')
    }
    // 3. 准备数据
    const record = {
      planId: this.planId,
      studentName: this.patientName,
      studentId: this.patientId,
      issljz: this.issljz,
      jzfs: this.jzfs,
      dzbSlREye: this.rightEyeVision,
      dzbSlLEye: this.leftEyeVision,
	  screenType: this.screenType
    }
    console.log('📤 【提交数据】:', JSON.stringify(record))
    // 4. 发起请求（添加超时控制）
    const response = await Promise.race([
      smYkScreenAdd(record),
      new Promise((_, reject) => 
        setTimeout(() => reject(new Error('请求超时，请检查网络连接')), 8000)
      )
    ])
    console.log('✅ 【后台响应】:', response)
    // 5. 处理响应
    if (response && response.code === 200) {
      uni.showToast({ 
        title: '保存成功', 
        icon: 'success',
        duration: 3000  // 3秒
      })
      // 成功后的重置
      this.sendReset()
      this.clearLogs()
      console.log('🎉 【保存成功】数据已提交到后台')
    } else {
      // 后台返回业务错误
      const errorMsg = response?.msg || response?.message || '保存失败，请重试'
      throw new Error(errorMsg)
    }
    
  } catch (e) {
    console.error('❌ 【保存错误详情】:', e)
    // 6. 安全地处理错误信息
    let errorMsg = e.message || '保存失败，请重试'
    // 7. 显示错误提示
    uni.showToast({ 
      title: errorMsg, 
      icon: 'none',
      duration: 4000  // 4秒
    })    
  } finally {
    // 8. 确保隐藏加载提示
    setTimeout(() => {
      uni.hideLoading()
    }, 300)
  }
},
    //扫用户码
    scanQRCode() {
      uni.scanCode({
        success: (res) => {
          const info = res.result.split(',')
          if (info.length >= 3) {
            this.patientName = info[2]
            this.patientId = info[5]
			this.planId = info[1]
            this.classInfo = info[6]
			this.screenType=info[4]
		    const patientInfo = {
			  name:this.patientName,
			  id: this.patientId,
			}
			this.sendCommand('setPatient', patientInfo);
          }
        }
      })
    },
    
    // 设置相关
    showSettings() {
      this.$refs.settingsPopup.open()
    },
    
    closeSettings() {
      this.$refs.settingsPopup.close()
    },
    
    // 目标设备扫码
	scanDeviceId() {
	  uni.scanCode({
	    success: (res) => {
		 const msg = JSON.parse(res.result)
	      this.targetDeviceId = msg.deviceId; // 直接使用扫码结果
	      uni.showToast({ title: '扫码成功', icon: 'success' });
	    },
	    fail: (err) => {
	      uni.showToast({ title: '扫码失败', icon: 'none' });
	    }
	  });
	},
    
    // 设置距离
    distanceChange(e) {
      this.currentDistance = parseFloat(e.detail.value)
      if (this.currentDistance) {
        this.sendCommand('setDefaultVision')
      }
    },
	
	// 设置默认视力
	defaultVisionChange(e) {
	   this.defaultVisionIndex = e.detail.value;
       this.currentDefaultVision=this.visionOptions[this.defaultVisionIndex].value;
	 // 发送新的初始视力设置
	 if (this.currentDefaultVision) {
	   this.sendCommand('setDefaultVision')
	 }
   },
   
    toggleLogs(value) {
      this.showLogs = !!value;
      
      this.$nextTick(() => {
        if (!this.$refs.logPopup) {
          console.warn('logPopup ref 未找到');
          return;
        }
        
        if (this.showLogs) {
          this.$refs.logPopup.open();
        } else {
          this.$refs.logPopup.close();
        }
      });
    },
    
    // 日志管理
    addLog(message) {
      const time = new Date().toLocaleTimeString()
      this.logs.unshift({ time, message })
      if (this.logs.length > 100) {
        this.logs.pop()
      }
    },
    
    clearLogs() {
      this.logs = []
    },
	onCorrectionChange(e) {
	  this.correctionIndex = e.detail.value;
     this.jzfs = this.correctionOptions[this.correctionIndex];
	  if(this.jzfs === '未矫正' ){
		  this.issljz='否';
	  }else{
		  this.issljz='是';
	  }
	},
  }
}
</script>

<style scoped>

.container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  overflow: hidden;
}

.header {
  margin-bottom: 20px;
  text-align: center;
}

.title {
  font-size: 22px;
  font-weight: bold;
  color: #333;
}

/* 信息卡片样式 */
.info-card {
  flex: 0 0 auto;
  background-color:#F2F2F2;
  padding: 16px;
}

.info-section {
  margin-bottom: 12px;
}

.section-title {
  font-size: 16px;
  font-weight: bold;
  color: #333;
  margin-bottom: 12px;
  display: block;
}

.info-row {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
  font-size: 14px;
}

.info-value {
  margin-left: 8px;
  color: #666;
}

.connected {
  color: #4CAF50;
}

.info-input {
  flex: 1;
  margin-left: 8px;
  padding: 4px 8px;
  border-bottom: 1px solid #eee;
  font-size: 14px;
}

.vision-row {
  display: flex;
  justify-content: space-between;
  margin-top: 12px;
}

.eye-vision {
  width: 48%;
}

.vision-value {
  font-size: 16px;
  color: #2196F3;
  margin-left: 8px;
}


/* 设备信息显示区域 */
.device-info-display {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 6px 0;     /* 原来 12px，减小 6px */
  width: 100%;
  margin-top: -30px;
}

/* 视力显示区域 */
.vision-display-area {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  margin: 0 0;        /* 原来 2px 0，改为 0 */
  background-color: #F2F2F2;
}

/* E字画布容器 */
.e-chart-container {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 150px;
  height: 150px;
  margin: 0 20px;
}

/* E字画布样式 - 无边框，透明背景 */
.e-canvas {
  width: 120px;
  height: 120px;
  display: block;
}

/* 等级视力显示（左侧） */
.level-vision {
  font-size: 32px;
  font-weight: bold;
  color: #333;
  min-width: 60px;
  text-align: center;
}

/* 小数视力显示（右侧） */
.decimal-vision {
  font-size: 32px;
  font-weight: bold;
  color: #333;
  min-width: 60px;
  text-align: center;
}

/* 状态行容器 */
.status-line {
  display: flex;
  width: 100%;
  justify-content: space-between;
  align-items: center;
  padding: 0 10px;
   margin-top: -30px;
}

/* 方向信息部分 */
.direction-info {
  display: flex;
  align-items: center;
  font-size: 16px;
  margin: 0 16px;
}

.direction-value {
  color: #666;
  font-size: 14px;
}

/* 状态信息部分 */
.status-info {
  display: flex;
  align-items: center;
  font-size: 15px;
  flex-shrink: 0; /* 防止被压缩 */
}

/* 状态圆点 */
.status-dot {
  font-size: 18px; /* 增大一点 */
  margin-right: 6px;
  color: #FF5252; /* 未连接时的红色 */
}

/* 已连接时的状态圆点 */
.status-dot.connected {
  color: #4CAF50; /* 已连接时的绿色 */
  animation: blink-animation 1.5s infinite;
}

/* 状态文字 */
.connect-status {
  color: #FF5252; /* 未连接时的红色 */
  font-size: 14px;
}

/* 已连接时的状态文字 */
.connect-status.connected {
  color: #4CAF50; /* 已连接时的绿色 */
}

/* 闪烁动画 */
@keyframes blink-animation {
  0% { opacity: 1; }
  50% { opacity: 0.7; }
  100% { opacity: 1; }
}
/* 分割线 */
.divider {
  height: 1px;
  background-color: #eee;
  margin: -16px 0 8px 0;
  width: 100%;
}

/* 控制区 */
.grid-container {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  background-color: #fff;
  overflow: hidden;
  margin-bottom: 20rpx;
}

.grid-row {
  display: flex;
  flex: 1 1 auto;
}

.grid-btn {
  flex: 1;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  color: #333;
  background-color: #fff;
  border: 1px solid #f2f2f2; 
  border-radius: 0; 
  border-right-width: 1px; /* 右边框 */
  border-bottom-width: 1px; /* 底边框 */
}

/* 重置 uni-button:after 的样式 */
.grid-btn:after {
  border: none !important; /* 确保没有额外的边框 */
  border-radius: 0 !important; /* 确保没有圆角 */
  box-shadow: none !important; /* 确保没有阴影 */
}

.grid-btn:active {
  background-color: #e5e5e5;   
}

.grid-row:last-child .grid-btn {
  border-bottom-width: 0; /* 最后一行的按钮去掉底边框 */
}

.grid-btn:last-child {
  border-right-width: 0; /* 最后一列的按钮去掉右边框 */
}

.grid-btn.primary {
  background-color: #2196F3;
  color: white;
}

/* 设置弹窗样式 */
.custom-dialog {
  width: 90vw;
  background: #fff;
  border-radius: 12px;
  overflow: hidden;
}

.dialog-header {
  padding: 16px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid #f0f0f0;
}

.dialog-title {
  font-size: 18px;
  font-weight: bold;
}

.close-icon {
  padding: 8px;
}

.dialog-body {
  padding: 16px;
  max-height: 60vh;
  overflow-y: auto;
}

.setting-item {
  margin-bottom: 20px;
}

.setting-label {
  display: block;
  font-size: 14px;
  color: #666;
  margin-bottom: 8px;
}

/* 输入框容器 */
.input-container {
  display: flex;
  align-items: stretch;
  height: 40px;
  margin-bottom: 12px;
}

/* 输入框样式 */
.setting-input {
  flex: 1;
  height: 100%;
  border: 1px solid #ddd;
  border-radius: 6px 0 0 6px;
  padding: 0 12px;
  font-size: 14px;
}

/* 扫码按钮 */
.scan-btn {
  width: 40px;
  height: 100%;
  background: #f5f5f5;
  border: 1px solid #ddd;
  border-left: none;
  border-radius: 0 6px 6px 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}

/* 连接按钮 */
.connect-btn {
  width: 100%;
  height: 40px;
  background-color: #4CAF50;
  color: white;
  border-radius: 6px;
  font-size: 14px;
  border: none;
}

.distance-radio {
  display: flex;
  flex-direction: column;
  margin-top: 8px;
}

.radio-item {
  display: flex;
  align-items: center;
  height: 40px;
  font-size: 14px;
}

radio {
  margin-right: 8px;
}

.picker-view {
padding: 6px;
border: 1px solid #ddd;
border-radius: 6px;
background-color: #fff;
margin-top: 0px;
}

.log-switch {
  float: right;
}

/* 日志面板样式 */
.log-panel {
  background-color: #fff;
  border-radius: 16px 16px 0 0;
  padding: 16px;
  max-height: 60vh;
}

.log-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}

.log-title {
  font-size: 16px;
  font-weight: bold;
}

.log-content {
  max-height: 50vh;
}

.log-item {
  font-size: 12px;
  line-height: 1.6;
  margin-bottom: 6px;
  word-break: break-all;
}

.log-time {
  color: #888;
  margin-right: 6px;
}

.clear-btn {
  background: none;
  border: none;
  padding: 0;
}
</style>